<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <h1>点我试试</h1>
    <script>
        // this 是js的一个关键字  
        // this 要么在全局范围 
        //  要么在函数内 

        // 全局范围  this => window 
        // alert(this);

        // 函数内this的指向  


        // 普通函数   this -> window 

        // 赋值函数   this->window 

        // 对象函数   this-> 对象本身 

        // 定时器     this -> window 

        // 事件处理函数  this ->事件源 

        // 数组高级方法   this->window 


        // 强制改变this指向  
        // 函数内 不管this指向哪  我想让你指向哪 就指向哪 
        

        // call
        // 语法:
        //      函数名.call()
        //      对象.函数名.call()
        // 参数:
        //      参数1: 该函数this指向 你想指向谁 这里就写谁 
        //      参数2及其它:依次给函数形参赋值 
        // 特点:
        //      立即调用 


        // apply
        // 语法:
        //      函数名.apply()
        //      对象.函数名.apply()
        // 参数:
        //      参数1: 该函数this指向 你想指向谁 这里就写谁 
        //      参数2: 是个数组 数组的元素依次给函数形参赋值 
        // 特点:
        //      立即调用 



        // bind
        // 语法:
        //      函数名.bind()
        //      对象.函数名.bind()
        // 参数:
        //      参数1: 该函数this指向 你想指向谁 这里就写谁 
        //      参数2开始:依次给函数的形参赋值

        // 特点:
            // 不会立即调用函数 而是返回一个新的函数 
            // 返回的函数跟原始函数一样  只不过是 改变了this





        // call 


        // 准备数据 

        // var obj = {name:'张三',age:18};
        // var arr = ['蔡*坤','吴*凡','李*峰'];

        // function fn(a,b){
        //     console.group('fn内函数的打印');
        //     console.log('a',a);
        //     console.log('b',b);
        //     console.log('this',this);
        //     console.groupEnd();

        // }

        // // 普通调用
        // fn(10,20)

        // // 利用call调用 
        // fn.call(obj,10,20);
        // fn.call(arr,10,20);


        // apply
        // 准备数据 

        // var obj = {name:'张三',age:18};
        // var arr = ['蔡*坤','吴*凡','李*峰'];

        // function fn2(a,b){
        //     console.group('fn2内函数的打印');
        //     console.log('a',a);
        //     console.log('b',b);
        //     console.log('this',this);
        //     console.groupEnd();

        // }

        // fn2(100,200);//  this->window

        // fn2.apply(obj,[100,200]);
        // fn2.apply(arr,[100,200]);



        // bind

        // 准备数据 

        var obj = {name:'张三',age:18};
        var arr = ['蔡*坤','吴*凡','李*峰'];

        function fn3(a,b){
            console.group('fn内函数的打印');
            console.log('a',a);
            console.log('b',b);
            console.log('this',this);
            console.groupEnd();

        }

        // 普通调用
        // fn3(10,20)
        // console.log(fn3.bind(obj,10,20)); 返回1个函数 跟原始函数一样
        
        // var res = fn3.bind(obj,10,20);

        // res()


        // var res2 = fn3.bind(arr,10,20);

        // res2()


        // ? 改变定时器this的指向 

        // setTimeout(function(){
        //     alert(this);
        // },1000);


        // var obj = {name:'张三',age:18};
        // var arr = ['蔡*坤','吴*凡','李*峰'];

        // function test1(){
        //     console.log(this);
        // }

        //  setTimeout(test1.call(obj),5000); 
        //test1.call(obj) 立即执行test1 
        // 定时器是延时执行 
        // 所以call  apply 不适用于定时器改变this指向 
        // setTimeout(test1.bind(obj),5000); 
        // 使用bind 返回一个新的函数 这个函数改变了this指向 
        // 5秒后执行这个新函数  this是改变后的 



        // ? 事件处理函数 改变this指向 


        // function test2(){
        //     console.log(this);
        // }
        // // document.getElementsByTagName('h1')[0].onclick = test2.call(obj);

        // // 事件处理函数 当触发事件才会执行 不能立即执行 
        // // call  apply 都是立即执行  所以不适用 

        // document.getElementsByTagName('h1')[0].onclick = test2.bind(obj);
        

        
    </script>
</body>
</html>